﻿using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace SF.Express.Sdk.Helper
{
    public class XmlHelper
    {
        /// <summary>
        /// 将对象序列化成XML字符串
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="o"></param>
        /// <returns></returns>
        public static string Serialize<T>(T o)
        {
            Encoding encoding = Encoding.UTF8;
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = encoding;
            settings.Indent = false;
            settings.OmitXmlDeclaration = true;

            // 添加空命名空间,不然序列化后会默认带2个xmlns
            XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
            namespaces.Add(prefix: string.Empty, ns: string.Empty);

            using (MemoryStream memoryStream = new MemoryStream())
            {
                XmlSerializer serializer = new XmlSerializer(type: o.GetType());
                using (XmlWriter xmlWriter = XmlWriter.Create(output: memoryStream, settings: settings))
                {
                    serializer.Serialize(xmlWriter: xmlWriter, o: o, namespaces: namespaces);
                }
                memoryStream.Position = 0;
                using (StreamReader streamReader = new StreamReader(stream: memoryStream, encoding: encoding))
                {
                    string xmlString = streamReader.ReadToEnd();
                    return xmlString;
                }
            }
        }

        /// <summary>
        /// 将XML字符串反序列化成对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="s"></param>
        /// <returns></returns>
        public static T Deserialize<T>(string s)
        {
            if (string.IsNullOrEmpty(s)) throw new ArgumentNullException(paramName: "s");

            Encoding encoding = Encoding.UTF8;
            XmlSerializer xmlSerializer = new XmlSerializer(type: typeof(T), defaultNamespace: string.Empty);
            using (MemoryStream memoryStream = new MemoryStream(buffer: encoding.GetBytes(s: s)))
            {
                using (StreamReader streamReader = new StreamReader(stream: memoryStream, encoding: encoding))
                {
                    return (T)xmlSerializer.Deserialize(textReader: streamReader);
                }
            }
        }
    }
}
